import { Message } from '@arco-design/web-vue';
import axios from 'axios';
import type { AxiosInstance, InternalAxiosRequestConfig, AxiosResponse } from 'axios';
import NProgress from 'nprogress';

import type { ApiResponse, RequestConfig } from '@/types/api';

// 创建 axios 实例
const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
  timeout: 15000,
  headers: {
    'Content-Type': 'application/json'
  }
});

// 当前请求数量（用于控制 Loading）
let requestCount = 0;

// 显示 Loading
const showLoading = () => {
  if (requestCount === 0) {
    NProgress.start();
  }
  requestCount++;
};

// 隐藏 Loading
const hideLoading = () => {
  requestCount--;
  if (requestCount <= 0) {
    requestCount = 0;
    NProgress.done();
  }
};

// 请求拦截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig & RequestConfig) => {
    // 显示 Loading（默认显示）
    if (config.showLoading !== false) {
      showLoading();
    }

    // 添加认证 token
    const token = localStorage.getItem('access_token');
    if (token && config.headers) {
      config.headers.Authorization = `Bearer ${token}`;
    }

    // 添加请求时间戳（防止缓存）
    if (config.method === 'get') {
      config.params = {
        ...config.params,
        _t: Date.now()
      };
    }

    return config;
  },
  (error) => {
    hideLoading();
    console.error('请求拦截器错误:', error);
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse<ApiResponse>): any => {
    const config = response.config as InternalAxiosRequestConfig & RequestConfig;

    // 隐藏 Loading
    if (config.showLoading !== false) {
      hideLoading();
    }

    const { data } = response;

    // 处理文件下载
    if (response.headers['content-type']?.includes('application/octet-stream')) {
      return response;
    }

    // HTTP状态码是200-299，检查业务状态码
    if (response.status >= 200 && response.status < 300) {
      // 正常返回数据
      return data;
    }

    // HTTP状态码不是2xx，这里不应该到达，但保留兜底逻辑
    const errorMessage = data?.message || '请求失败';
    if (config.showError !== false) {
      Message.error(errorMessage);
    }
    throw new Error(errorMessage);
  },
  (error) => {
    const config = error.config as InternalAxiosRequestConfig & RequestConfig;

    // 隐藏 Loading
    if (config?.showLoading !== false) {
      hideLoading();
    }

    let errorMessage = '网络错误，请稍后重试';

    if (error.response) {
      const { status, data } = error.response;
      // 优先使用后端返回的错误信息
      const backendMessage = data?.message;
      switch (status) {
        case 400:
          errorMessage = backendMessage || '请求参数错误';
          break;
        case 401:
          errorMessage = backendMessage || '登录已过期，请重新登录';
          localStorage.removeItem('access_token');
          // 只有在非退出登录接口时才显示错误信息
          if (config?.showError !== false && !error.config?.url?.includes('/auth/logout')) {
            Message.error(errorMessage);
          }
          window.location.href = '/login';
          return Promise.reject(new Error(errorMessage));
        case 403:
          errorMessage = backendMessage || '没有权限访问此资源';
          break;
        case 404:
          errorMessage = backendMessage || '请求的资源不存在';
          break;
        case 500:
          errorMessage = backendMessage || '服务器内部错误';
          break;
        case 502:
          errorMessage = backendMessage || '网关错误';
          break;
        case 503:
          errorMessage = backendMessage || '服务暂时不可用';
          break;
        default:
          errorMessage = backendMessage || `请求失败 (${status})`;
      }
    } else if (error.code === 'ECONNABORTED') {
      errorMessage = '请求超时，请稍后重试';
    } else if (error.message === 'Network Error') {
      errorMessage = '网络连接失败，请检查网络';
    }

    // 显示错误消息（默认显示，但401错误已经在上面处理过）
    if (config?.showError !== false && error.response?.status !== 401) {
      Message.error(errorMessage);
    }

    console.error('API 请求错误:', error);
    return Promise.reject(new Error(errorMessage));
  }
);

export default service;
